﻿#define _CRT_SECURE_NO_WARNINGS


//class A
//{
////    friend class B;//这样就可以了
////private:
////    int _val;
//public:
//    //A(int i)
//    //{
//    //    B b;
//    //    b._val = 1;
//    //}
//    A(int i);
//};
//
//class B
//{
//    friend A::A(int i);
////public:
////    void fun(A& a)
////    {
////        a._val = 1;//这样不行, 因为 _val 是 A 的私有成员变量                
////    }
//private:
//    int _val;
//};
//
//A::A(int i)
//{
//    B b;
//    b._val = 1;
//}

//class C//要让 C 的成员函数成为 D 的友元, 这样不行
//{
//public:
//    void fun()
//    {
//        D d;
//        d._val = 1;
//    }
//};
//
//class D
//{
//    friend void C::fun();
//private:
//    int _val;
//};
//
//class C//要让 C 的成员函数成为 D 的友元, 这样才可以
//{
//public:
//    void fun();
//};
//
//class D
//{
//    friend void C::fun();
//private:
//    int _val;
//};
//
//void C::fun()
//{
//    D d;
//    d._val = 1;
//}

//class C//要让 C 的(默认)构造函数成为 D 的友元, 这样不行
//{
//public:
//    C(int i = 1)
//    {
//        D d;
//        d._val = 1;//VS2022 这里会报错, 提示访问受限(即使有友元声明)
//    }
//};
//
//class D
//{
//    friend C::C(int i);
//private:
//    int _val;
//};
//
//class C//要让 C 的(默认)构造函数成为 D 的友元, 这样才可以
//{
//public:
//    C(int i = 1);//默认构造函数的声明, 声明和定义分离时, 缺省值只能在这出现
//};//必须做声明和定义的分离, 不然无法实现
//
//class D
//{
//    friend C::C(int i);//友元声明必须在 A 的成员函数的声明后写
//private:
//    int _val;
//};
//
//C::C(int i)//定义必须放在外部
//{
//    D d;//并且由于使用了 D 类, 这个实现必须在 D 类后面
//    d._val = 1;
//}//由于成员函数的声明, 友元声明, D 类定义的位置, C 类定义的位置, 成员函数的定义
////这几者的顺序是固定的, 要实现只能这样


//class C//要让 C 的析构函数成为 D 的友元, 这样不行
//{
//public:
//    ~C()
//    {
//        D d;
//        d._val = 1;
//    }
//};
//
//class D
//{
//    friend C::~C();
//private:
//    int _val;
//};

//class C//要让 C 的析构函数成为 D 的友元, 这样才可以
//{
//public:
//    ~C();
//};
//
//class D
//{
//    friend C::~C();
//private:
//    int _val;
//};
//
//C::~C()
//{
//    D d;
//    d._val = 1;
//}

//class C//要让 C 的拷贝构造函数成为 D 的友元, 这样不行
//{
//public:
//    C(C& c)
//    {
//        D d;
//        d._val = 1;
//    }
//};
//
//class D
//{
//    friend C::C(C& c);
//private:
//    int _val;
//};

//class C//要让 C 的拷贝构造函数成为 D 的友元, 这样才可以
//{
//public:
//    C(C& c);
//};
//
//class D
//{
//    friend C::C(C& c);
//private:
//    int _val;
//};
//
//C::C(C& c)
//{
//    D d;
//    d._val = 1;
//}

//class C//要让 C 的赋值运算符重载成为 D 的友元, 这样不行
//{
//    C& operator=(const C& c)
//    {
//        D d;
//        d._val = 1;
//    }
//};
//
//class D
//{
//    friend C& C::operator=(const C& c);
//private:
//    int _val;
//};

//class C//要让 C 的赋值运算符重载成为 D 的友元, 这样才可以
//{
//public:
//    C& operator=(const C& c);
//};
//
//class D
//{
//    friend C& C::operator=(const C& c);
//private:
//    int _val;
//};
//
//C& C::operator=(const C& c)
//{
//    D d;
//    d._val = 1;
//    C ret;
//    return ret;
//}

//#include <iostream>
//
//class A
//{
//private:
//    int _a1;
//    static int _a2;
//public:
//    class B
//    {
//    private:
//        int _b1;
//        int _b2;
//    };
//};
//
//int main()
//{
//    //B b;
//    //A a;
//    //b.fun(a);
//    std::cout << sizeof(A) << std::endl;
//
//    return 0;
//}

//class A
//{
//public:
//	void fun()
//	{
//		//...
//	}
//};
//
//int main()
//{
//	A().fun();
//
//	return 0;
//}


//#include<iostream>
//using namespace std;
//class A
//{
//public:
//    A(int a = 0)
//        :_a1(a)
//    {
//        cout << "A(int a)" << endl;
//    }
//    A(const A& aa)
//        :_a1(aa._a1)
//    {
//        cout << "A(const A& aa)" << endl;
//    }
//    A& operator=(const A& aa)
//    {
//        cout << "A& operator=(const A& aa)" << endl;
//        if (this != &aa)
//        {
//            _a1 = aa._a1;
//        }
//        return *this;
//    }
//    ~A()
//    {
//        cout << "~A()" << endl;
//    }
//private:
//    int _a1 = 1;
//};
//
//void f1(A aa) {}
//
//A f2()
//{
//    A aa;
//    return aa;
//}
//int main()
//{
//    // 传值传参
//
//    // 构造+拷⻉构造
//    cout << "***********************************************" << endl;
//    A aa1;
//    f1(aa1);
//    // 隐式类型, 连续构造+拷⻉构造->优化为直接构造
//    cout << "***********************************************" << endl;
//    f1(1);
//    // ⼀个表达式中, 连续构造+拷⻉构造->优化为⼀个构造
//
//    cout << "***********************************************" << endl;
//    f1(A(2));
//    cout << "***********************************************" << endl;
//    // 传值返回
//    // 不优化的情况下传值返回, 编译器会⽣成⼀个拷⻉返回对象的临时对象作为函数调⽤表达式的返回值        
//    // ⽆优化 (vs2019 debug)
//    // ⼀些编译器会优化得更厉害, 将构造的局部对象和拷⻉构造的临时对象优化为直接构造 (vs2022 debug)
//
//    f2();
//    cout << "***********************************************" << endl;
//    // 返回时⼀个表达式中, 连续拷⻉构造+拷⻉构造->优化⼀个拷⻉构造 (vs2019 debug)
//    // ⼀些编译器会优化得更厉害, 进⾏跨⾏合并优化, 将构造的局部对象aa和拷⻉的临时对象和接收返回值对象aa2优化为⼀个直接构造 (vs2022 debug)
//
//    A aa2 = f2();
//    cout << "***********************************************" << endl;
//    // ⼀个表达式中, 开始构造, 中间拷⻉构造+赋值重载->⽆法优化 (vs2019 debug)
//
//    aa1 = f2();
//    cout << "***********************************************" << endl;
//    return 0;
//}

//我们先来看下面的一段代码和相关问题
//int globalVar = 1;
//static int staticGlobalVar = 1;
//void Test()
//{
//	static int staticVar = 1;
//	int localVar = 1;
//	int num1[10] = { 1, 2, 3, 4 };
//	char char2[] = "abcd";
//	const char* pChar3 = "abcd";
//	int* ptr1 = (int*)malloc(sizeof(int) * 4);
//	int* ptr2 = (int*)calloc(4, sizeof(int));
//	int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4);
//	free(ptr1);
//	free(ptr3);
//}
//1. 选择题：
//选项 : A.栈  B.堆  C.数据段(静态区)  D.代码段(常量区)
//globalVar在哪里？____
//staticGlobalVar在哪里？____
//staticVar在哪里？____
//localVar在哪里？____
//num1 在哪里？____
//char2在哪里？____
//* char2在哪里？___
//pChar3在哪里？____
//* pChar3在哪里？____
//ptr1在哪里？____
//* ptr1在哪里？____

// C C C A A
// A A A D A B

//#include <iostream>
//
//typedef int type;
//
//int main()
//{
//	int num = 10;
//
//	// new/delete 用于申请/释放单块空间
//	type* p1 = new type;// 申请一块 type 类型的空间
//	type* p2 = new type(num);// 申请一块 type 类型的空间, 并初始化为 num
//	delete p1;// 释放 new 申请的空间必须使用 delete
//	delete p2;
//
//	// new[]/delete[] 用于申请/释放连续整块的空间
//	type* p3 = new type[num];// 申请大小为 num 个 type 的空间
//	delete[] p3;// 释放 new[] 申请的空间必须使用 delete[]
//
//	return 0;
//}

//#include <iostream>
//using namespace std;
//
//class BLZ
//{
//public:
//	BLZ()
//	{
//		cout << "BLZ()" << endl;
//	}
//	~BLZ()
//	{
//		cout << "~BLZ()" << endl;
//	}
//};
//
//int main()
//{
//	int num = 3;
//	BLZ* pblz;
//	cout << "malloc/free:" << endl;
//	pblz = (BLZ*)malloc(num * sizeof(BLZ));
//	free(pblz);
//
//	cout << "new/delete:" << endl;
//	pblz = new BLZ;
//	delete pblz;
//
//	cout << "new[]/delete[]:" << endl;
//	pblz = new BLZ[num];
//	delete[] pblz;
//
//	return 0;
//}

//#include <cstdlib>
//#include <iostream>
//
//using namespace std;
//
//int main()
//{
//	size_t i = 0;
//	int* ptr = nullptr;
//	try
//	{
//		do
//		{
//			//ptr = (int*)malloc(1024 * 1024 * 1024);
//			ptr = new int[1024 * 1024 * 1024 / 4];
//		} while (ptr);
//	}
//	catch (const exception& e)
//	{
//		cout << e.what() << endl;
//	}
//	cout << i << endl;
//	cout << i / (1024 * 1024) << endl;
//
//	return 0;
//}

//#include <iostream>
//
//using namespace std;
//
//class A
//{
//private:
//	int _val;
//public:
//	//A()
//	//{
//
//	//}
//	~A()
//	{
//		cout << "~A()" << endl;
//	}
//};
//
//int main()
//{
//	A* ptr = new A[5];
//	//delete ptr;
//	delete ((char*)ptr - 8);
//
//	return 0;
//}

//#include <iostream>
//using namespace std;
//
//double Div(double d1, double d2)
//{
//	if (d2 == 0)
//	{
//		throw "除数不能为 0!!!";
//	}
//	return d1 / d2;
//}
//
//int main()
//{
//    double d1 = 0, d2 = 0, result = 0;
//    cin >> d1 >> d2;
//    try
//    {
//        result = Div(d1, d2);
//    }
//    catch (const char* str)
//    {
//        cout << str << endl;
//        return 1;
//    }
//    cout << result << endl;
//
//    return 0;
//}

//class A
//{
//    int _val;
//public:
//    ~A()
//    {
//
//    }
//};
//
//int main()
//{
//    A* ptr = new A[10];//分配可以容纳 10 个 A 类对象的数组
//    return 0;
//}

//class A
//{
//private:
//    int _val;
//public:
//    ~A() {}// 这次我们显式定义析构函数
//};
//
//int main()
//{
//    A* ptr = new A[5];// 使用 new[] 创建
//    // 按照理论, 返回的指针 ptr 应该指向的是申请内存开头的后 4/8 个字节
//
//    // 仍然使用 delete 删除, 而不是 delete[]
//    //delete ((char*)ptr - 8);// 我的环境是 x64, 所以是往前数 8 字节
//    delete (ptr - 2);// x64 环境下这样写, 相当于减去两个 A 对象的大小, 也就是 8
//    //按照理论, 在 64 位环境下, (char*)ptr + 8 指向的就是申请内存的开头, 这样程序应该不会报错
//
//    return 0;
//}

//class A//使用 new 申请, delete[] 释放来验证理论
//{
//private:
//	int _val1 = 0;
//public:
//	~A() {}
//};
//
//class B
//{
//private:
//	int _val1 = 0;
//	int _val2 = 0;
//	int _val3 = 0;
//	int _val4 = 0;
//	int _val5 = 0;
//	int _val6 = 0;
//};
//
//int main()
//{
//	B* ptr2 = new B;
//	int* arr = (int*)ptr2;
//	arr[0] = 4;
//	delete[] (A*)((char*)ptr2 + 8);
//	//arr[0] = 5;
//	//delete[](A*)((char*)ptr2 + 4);
//
//	return 0;
//}

#include <iostream>

using namespace std;

int main()
{
	//int* ptr = nullptr;
	int a = 0;
	cin.exceptions(std::istream::failbit);// 设置 std::cin 在 failbit 状态时抛出异常
	try
	{
		//while (1)
		//{
		//	ptr = new int[1024 * 1024 * 1024 / 2];
		//}
		cin >> a;
	}
	catch (const std::ios_base::failure& e)
	{
		cout << e.what() << endl;
	}
	//catch (const exception& e)
	//{
	//	cout << e.what() << endl;
	//}

	return 0;
}